package com.hxtec.polaris.service.impl;

import com.google.common.util.concurrent.ThreadFactoryBuilder;
import com.hxtec.polaris.commons.api.vo.Result;
import com.hxtec.polaris.commons.constant.*;
import com.hxtec.polaris.commons.exception.MyException;
import com.hxtec.polaris.commons.thread.BuildPathRunable;
import com.hxtec.polaris.commons.utils.GenerateSequenceUtil;
import com.hxtec.polaris.entity.ShopCategory;
import com.hxtec.polaris.mapper.ShopCategoryMapper;
import com.hxtec.polaris.service.CategoryService;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import tk.mybatis.mapper.entity.Example;

import javax.annotation.Resource;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import java.text.MessageFormat;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ThreadFactory;

/**
 * @Describtion //分类相关service
 * @Author yonyong
 * @Date 2019/11/11 14:48
 * @Version 1.0.0
 **/
@Service
@Transactional
public class CategoryServiceImpl implements CategoryService {

    private final static Logger logger = LoggerFactory.getLogger(CategoryServiceImpl.class);
    private final static String LOG_CLASS_NAME = "CategoryServiceImpl";
    private final static String LOG_METHOD_ADD_CATORY = "addCategory";
    private final static String LOG_METHOD_DEL_CATORY = "deleteCategory";
    private final static String LOG_METHOD_UPDATE_CATORY ="updateCategory";

    @Resource
    private ShopCategoryMapper shopCategoryMapper;

    @Override
    public Object getAllCategory() {
        //查询表category获取对应的数据
        List<ShopCategory> list = shopCategoryMapper.getAllCategory();
        if (null !=list && list.size()>0){
            return Result.ok(list);
        }else {
            //查询失败或查询到的数据为空
            throw new MyException(Result.error(Code.FAIL_4101,Msg.CATEGORY_SELECT_NO));
        }
    }

    @Override
    public Object addCategory(HttpServletRequest request,String pid, String name,String img) {
        String params = "pid="+pid+",name="+name;
        String LOG_MSG = MessageFormat.format(Log.PATTERN_LOG,Log.INSERT,LOG_CLASS_NAME,LOG_METHOD_ADD_CATORY,params);

        //如果父节点为空，则添加的节点为一级节点，走一级节点添加方法
        if(StringUtils.isBlank(pid)){
            try {
                doAddRootCategory(request,name,img);
                return Result.ok(Msg.CATEGORY_INSERT_OK);
            }catch (Exception e){
                throw new MyException(Result.error(Code.FAIL_4101,Msg.CATEGORY_INSERT_EXCEPTION),LOG_MSG);
            }
        }

        //请求参数不合法
        if (!StringUtils.isNumeric(pid)){
            throw new MyException(Result.error(Code.FAIL_4101,Msg.PARAM_INVALID),LOG_MSG);
        }
        //判断数据库中是否有该父节点
        ShopCategory parentObject = shopCategoryMapper.selectByPrimaryKey(pid);
        if (null == parentObject){
            throw new MyException(Result.error(Code.FAIL_4101,Msg.CATEGORY_PNODE_NO),LOG_MSG);
        }
        //实例赋值
        ShopCategory shopCategory = setParam(pid,name);
        shopCategory.setImage(img);
        //数据新增入库
        try {
            doAddCategory(request,shopCategory,parentObject);
        }catch (Exception e){
            throw new MyException(Result.error(Code.FAIL_4101,Msg.CATEGORY_INSERT_EXCEPTION),LOG_MSG);
        }
        logger.info(LOG_MSG);
        return Result.ok(Msg.CATEGORY_INSERT_OK);
    }

    /**
     * 添加分类 如果父节点为空，则添加的节点为一级节点，走一级节点添加方法
     * @param request
     * @param name
     * @param img
     */
    private void doAddRootCategory(HttpServletRequest request, String name, String img) {
        ShopCategory shopCategory = new ShopCategory();
        shopCategory.setName(name);
        shopCategory.setImage(img);
        shopCategory.setIsParent("N");
        shopCategory.setIsDelete("N");
        shopCategory.setUpdateTime(new Date());
        shopCategory.setCreateTime(new Date());
        shopCategoryMapper.inserRootCategory(shopCategory);
        callBuildPath(request);
    }

    @Override
    public Object deleteCategory(HttpServletRequest request,List<String> ids) {
        String params = "ids="+ids;
        String LOG_MSG = MessageFormat.format(Log.PATTERN_LOG,Log.DELETE,LOG_CLASS_NAME, LOG_METHOD_DEL_CATORY,params);

        //参数为空
        if (null == ids || ids.size() == 0){
            throw new MyException(Result.error(Code.FAIL_4101,Msg.CATEGORY_DELETE_NO),LOG_MSG);
        }
        for (String id : ids){
            //参数不合法
            if (!StringUtils.isNumeric(id)){
                throw new MyException(Result.error(Code.FAIL_4101,Msg.PARAM_INVALID),LOG_MSG);
            }
            //更新shop_category表
            int deletCategoryResult = 0;
            try{
                deletCategoryResult = shopCategoryMapper.deleteCategory(id,new Date());
            }catch (Exception e){
                throw new MyException(Result.error(Code.FAIL_4101,Msg.CATEGORY_DELETE_EXCEPTION),LOG_MSG);
            }
            if (deletCategoryResult < 0){
                throw new MyException(Result.error(Code.FAIL_4101, Msg.CATEGORY_DELETE_FAIL),LOG_MSG);
            }

        }
        callBuildPath(request);
        logger.info(LOG_MSG);
        return Result.ok(Msg.CATEGORY_DELETE_OK);
    }

    @Override
    public Object updateCategory( String id, String name,String img) {
        String params = "id="+id+",name="+name;
        String LOG_MSG = MessageFormat.format(Log.PATTERN_LOG,Log.UPDATE,LOG_CLASS_NAME,LOG_METHOD_UPDATE_CATORY,params);
        if (!StringUtils.isNumeric(id) || StringUtils.isBlank(name)){
            throw new MyException(Result.error(Code.FAIL_4101,Msg.PARAM_INVALID),LOG_MSG);
        }
        //执行更新操作
        try {
            doUpdateShopCategory(id,name,img);
        }catch (Exception e){
            throw new MyException(Result.error(Code.FAIL_4101,Msg.CATEGORY_UPDATE_FAIL),LOG_MSG);
        }
        logger.info(LOG_MSG);
        return Result.ok(Msg.CATEGORY_UPDATE_OK);
    }

    @Override
    public Object buildTree(Integer id) {
        if (null == id){
            //初始化tree
            List<Map<String,Object>> mapList = shopCategoryMapper.getFirstTree();
            return Result.ok(mapList);
        }else {
            //获取下级分类信息
            List<Map<String,Object>> mapList = shopCategoryMapper.getChildTree(id);
            return Result.ok(mapList);
        }
    }

    @Override
    public Object selectTree(String condition) {
        List<Map<String,Object>> mapList = shopCategoryMapper.selectTree(condition);
        return Result.ok(mapList);
    }

    @Override
    public List<ShopCategory> getCatalog3(String catalog2Id) {
        Example example=new Example(ShopCategory.class);
        example.createCriteria().andEqualTo("parentId",catalog2Id)
                .andEqualTo("isDelete","N");
        return shopCategoryMapper.selectByExample(example);
    }

    @Override
    public List<ShopCategory> getCatalog2(String catalog1Id) {
        Example example=new Example(ShopCategory.class);
        example.createCriteria().andEqualTo("parentId",catalog1Id)
                .andEqualTo("isDelete","N");
        return shopCategoryMapper.selectByExample(example);
    }

    @Override
    public List<ShopCategory> getCatalog1() {
        Example example=new Example(ShopCategory.class);
        example.createCriteria().andIsNull("parentId")
                .andEqualTo("isDelete","N");
        return shopCategoryMapper.selectByExample(example);
    }

    /**
     * ShopCategory实例赋值
     * @param pid
     * @param name
     * @return
     */
    private ShopCategory setParam(String pid, String name){
        ShopCategory shopCategory = new ShopCategory();
        //生成id
        shopCategory.setParentId(pid);
        shopCategory.setIsParent(GlobalVar.NO);
        shopCategory.setName(name);
        shopCategory.setIsDelete(GlobalVar.NO);
        shopCategory.setCreateTime(new Date());
        shopCategory.setUpdateTime(new Date());
        return shopCategory;
    }

    /**
     * 执行db层面的分类更新,返回t
     * @param id
     * @param name
     * @return
     */
    private void doUpdateShopCategory(String id, String name,String img){
        shopCategoryMapper.doUpdateShopCategory(id,name,img,new Date());
    }

    /**
     * @Author yonyong
     * @Description //执行db层面的分类insert,返回t
     * @Date 2019/11/20 14:36
     * @Param
     * @return
     **/
    private void doAddCategory(HttpServletRequest request,ShopCategory shopCategory,ShopCategory parentObject){
        shopCategoryMapper.insertCategory(shopCategory);
        //构建分类路径
       callBuildPath(request);
    }

    /**
     * 判断两个字符串是否相等 将"" 、"  "、null相同对待
     * @param str1
     * @param str2
     * @return
     */
    private boolean equalsIgnoreCase(String str1,String str2){
        str1 = StringUtils.isBlank(str1)? "":str1;
        str2 = StringUtils.isBlank(str2)? "":str2;
        return StringUtils.equals(str1, str2);
    }

    /**
     * 更新分类路径
     * @param request
     */
    private void callBuildPath(HttpServletRequest request){
        //调用线程，更新path
        //把当前编辑的节点及其所有子节点挂到新的节点下面，更新路径
        // 创建线程池
        ThreadFactory pool = new ThreadFactoryBuilder().setNameFormat(GlobalVar.THREAD_CATEGORY_BUILD_PATH).build();
        ServletContext context =  request.getServletContext();
        // 计数器
        CountDownLatch doneSignal = new CountDownLatch(1);
        pool.newThread(new BuildPathRunable(context,doneSignal)).start();
    }
}
